from __future__ import division
from classCluster import Cluster
from classEdge import Edge
import pickle
from math import sqrt
from SDset import SymbolicDisjointSet
#from getKeyWord import GetKeyWords
from calcKeywords import calcKeywords
import json
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def xy_sort(alist, aref):
    result = sorted(alist, key = aref.get)
    return result

def procJson(id_clusters):
    num_clusters = int(id_clusters.split('_')[1])
    infile = open("data/" + id_clusters + ".json", 'r')
    txt = infile.read()
    source_dict = json.loads(txt.decode("utf8", 'replace'))
    infile.close()
    nodes = source_dict.get('node')
    edges = source_dict.get('edge')
    clusters = {}
    for key in nodes:
        if clusters.get( nodes[key]['cluster'] ) == None:
            clusters[ nodes[key]['cluster'] ] = []
        clusters[ nodes[key]['cluster'] ].append(key)
    cluster_edges_weight = {}
    #
    cluster_edges_weight_year = {}
    cluster_edges_detail_year = {}
    #
    for edge in edges:
        source_node = nodes.get(edge['source'])
        target_node = nodes.get(edge['target'])
        if source_node != None and target_node != None:
            if cluster_edges_weight.get( (source_node['cluster'], target_node['cluster']) ) == None:
                cluster_edges_weight[(source_node['cluster'], target_node['cluster'])] = 0
            cluster_edges_weight[(source_node['cluster'], target_node['cluster'])] += 1
            #
            if cluster_edges_weight_year.get( (source_node['cluster'], target_node['cluster']) ) == None:
                cluster_edges_weight_year[ (source_node['cluster'], target_node['cluster']) ] = {}
            source_target_year = str(min(int(source_node['year']), int(target_node['year']))) + "-" + str(max(int(source_node['year']), int(target_node['year'])))
            if cluster_edges_weight_year[(source_node['cluster'], target_node['cluster'])].get(source_target_year) == None:
                cluster_edges_weight_year[(source_node['cluster'], target_node['cluster'])][source_target_year] = 0
            cluster_edges_weight_year[(source_node['cluster'], target_node['cluster'])][source_target_year] += 1
            #
            if cluster_edges_detail_year.get( (source_node['cluster'], target_node['cluster']) ) == None:
                cluster_edges_detail_year[ (source_node['cluster'], target_node['cluster']) ] = {}
            if cluster_edges_detail_year[(source_node['cluster'], target_node['cluster'])].get(source_target_year) == None:
                cluster_edges_detail_year[(source_node['cluster'], target_node['cluster'])][source_target_year] = list()
            cluster_edges_detail_year[(source_node['cluster'], target_node['cluster'])][source_target_year].append( (edge['source'], edge['target']) )
            #
    cluster_edges_flow = {}
    for key in cluster_edges_weight:
        cluster_edges_flow[key] = cluster_edges_weight[key] / sqrt(len(clusters[key[0]]) * len(clusters[key[1]]))
    list_flow = list(cluster_edges_flow)
    # calculate total flow rate
    total_flow_rate = 0
    for key in list_flow:
        total_flow_rate += cluster_edges_flow[key]
    print("total_flow_rate: " + str(total_flow_rate))
    #
    # sort list_flow
    #L = 2 * num_clusters
    L = len(list_flow)
    list_flow = xy_sort(list_flow, cluster_edges_flow)
    reserved = list_flow
    deleted = list()
    clusters_set = SymbolicDisjointSet(list(clusters))
    # join from rootCluster
    rootCluster = '300'
    #added = 1
    added = 0
    while added > 0:
        added = 0
        for cluster_edge in reserved:
            if clusters_set.getRoot(cluster_edge[0]) == clusters_set.getRoot(rootCluster):
                if clusters_set.getRoot(cluster_edge[1]) != clusters_set.getRoot(rootCluster):
                    clusters_set.join(cluster_edge[0], cluster_edge[1])
                    added += 1
    for cluster_edge in reversed(deleted):
        if clusters_set.getRoot(cluster_edge[0]) != clusters_set.getRoot(cluster_edge[1]):
            if clusters_set.getRoot(cluster_edge[0]) == clusters_set.getRoot('300'):
                clusters_set.join(cluster_edge[0], cluster_edge[1])
                reserved.append(cluster_edge)
        if clusters_set.size('300') >= len(clusters):
            break
    result_dict = {'cluster': {}, 'edge': []}
    for key in nodes:
        if result_dict['cluster'].get( str(nodes[key]['cluster']) ) == None:
            result_dict['cluster'][ str(nodes[key]['cluster']) ] = Cluster()
        #
        corresponding_node = nodes[key]
        node_year = corresponding_node['year']
        node_cluster = corresponding_node['cluster']
        node_id = corresponding_node['id']
        if result_dict['cluster'][ str(node_cluster) ].year_and_id.get(node_year) == None:
            result_dict['cluster'][ str(node_cluster) ].year_and_id[node_year] = list()
        result_dict['cluster'][ str(node_cluster) ].year_and_id[node_year].append(node_id)
        #
        #result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist.append(key)
        tmp_node_dict = {}
        result_dict['cluster'][ str(nodes[key]['cluster']) ].nodes.append(tmp_node_dict)
        for datum in list(nodes[key]):
            tmp_node_dict[datum] = nodes[key][datum]
        if tmp_node_dict.get('abstract') == None:
            tmp_node_dict['abstract'] = ''
        #result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist.append([tmp_node_dict['id'], tmp_node_dict['year']])
        if type(result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist) != dict:
            result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist = dict()
        if result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist.get(str(tmp_node_dict['year'])) == None:
            result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist[str(tmp_node_dict['year'])] = list()
        result_dict['cluster'][ str(nodes[key]['cluster']) ].nodeidlist[str(tmp_node_dict['year'])].append(tmp_node_dict['id'])
    #
    #keyWord = GetKeyWords()
    #keyWord.dataLoader(result_dict['cluster'])
    #keyWord.nounloader()
    #keyWord.main()
    calcKeywords(result_dict['cluster'])
    #
    for cluster_edge in reserved:
        tmp_edge = Edge()
        tmp_edge.source = cluster_edge[0]
        tmp_edge.target = cluster_edge[1]
        #tmp_edge.weight = cluster_edges_weight[cluster_edge]
        tmp_edge.weight = cluster_edges_weight_year[cluster_edge]
        tmp_edge.flow = cluster_edges_flow[cluster_edge]
        tmp_edge.edge_detail = cluster_edges_detail_year[cluster_edge]
        result_dict['edge'].append(tmp_edge)
    outfile = open("data/result/" + id_clusters + ".json", 'w')
    pickle.dump(result_dict, outfile)
    outfile.close()
    print("procJson finished")
    return result_dict